home *** CD-ROM | disk | FTP | other *** search
/ Aminet 2 / Aminet AMIGA CDROM (1994)(Walnut Creek)[Feb 1994][W.O. 44790-1].iso / Aminet / gfx / edit / TSMrph23s.lha / TSM23s.lha / Frames.c < prev    next >
C/C++ Source or Header  |  1993-10-08  |  10KB  |  310 lines

  1. // TSMorph - Amiga Morphing program
  2. // Copyright (C) © 1993  Topicsave Limited
  3.  
  4. // This program is free software; you can redistribute it and/or modify
  5. // it under the terms of the GNU General Public License as published by
  6. // the Free Software Foundation; either version 2 of the License, or
  7. // any later version.
  8.  
  9. // This program is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12. // GNU General Public License for more details.
  13.  
  14. // You should have received a copy of the GNU General Public License
  15. // along with this program; if not, write to the Free Software
  16. // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17.  
  18. // mpaddock@cix.compulink.co.uk
  19.  
  20. //    $Author: M_J_Paddock $
  21. //    $Date: 1993/08/28 22:02:58 $
  22. //    $Revision: 1.5 $
  23.  
  24. // include headers if not precompiled
  25. #ifndef TSMORPH_H
  26. #include "TSMorph.h"
  27. #endif
  28.  
  29. LONG OldFrame;        // Previous frame number
  30.  
  31. /* Go to the first frame
  32.  * the return value is that used by the main message loop
  33.  */
  34. int
  35. FirstFrame(void) {
  36.     OldFrame=FrameNumber;                // Store old frame
  37.     FrameNumber = GetNumber(TSMorphGadgets[GDX_Start]);    // get starting frame
  38.     if (FrameNumber != OldFrame) {    // if different
  39.         return ReopenPictures();        // try and move to new frame
  40.     }
  41.     return 1;
  42. }
  43.  
  44. /* Go to the previous frame
  45.  * See FirstFrame()
  46.  */
  47. int
  48. PrevFrame(void) {
  49.     OldFrame=FrameNumber;
  50.     if (FrameNumber > GetNumber(TSMorphGadgets[GDX_Start])) {
  51.         --FrameNumber;    // previous frame
  52.         return ReopenPictures();
  53.     }
  54.     return 1;
  55. }
  56.  
  57. /* Go to the previous frame
  58.  * See FirstFrame()
  59.  */
  60. int
  61. GotoFrame(void) {
  62.     OldFrame=FrameNumber;
  63.     GetFrameNumber();    // Request frame number
  64.     if (FrameNumber != OldFrame) {
  65.         return ReopenPictures();
  66.     }
  67.     return 1;
  68. }
  69.  
  70. /* Go to the next frame
  71.  * See FirstFrame()
  72.  */
  73. int
  74. NextFrame(void) {
  75.     OldFrame=FrameNumber;    // next determine last frame number
  76.     if (FrameNumber < (GetNumber(TSMorphGadgets[GDX_Start]) + GetNumber(TSMorphGadgets[GDX_Frames]) -1)) {
  77.         ++FrameNumber;
  78.         return ReopenPictures();
  79.     }
  80.     return 1;
  81. }
  82.  
  83. /* Go to the last frame
  84.  * See NextFrame()
  85.  */
  86. int
  87. LastFrame(void) {
  88.     OldFrame=FrameNumber;
  89.     FrameNumber = GetNumber(TSMorphGadgets[GDX_Start]) + GetNumber(TSMorphGadgets[GDX_Frames]) - 1;
  90.     if (FrameNumber != OldFrame) {
  91.         return ReopenPictures();
  92.     }
  93.     return 1;
  94. }
  95.  
  96. /* Request frame number
  97.  * returns TRUE if not cancelled
  98.  * selected frame is stored in FrameNumber
  99.  * This could use a nice sliding gadet requester - actually uses reqtools
  100.  */
  101. BOOL
  102. GetFrameNumber(void) {
  103.     LONG     Frames, Start;            // Number of frames and starting frame
  104.     ULONG ret = 2;                    // loop flag
  105.     struct AmigaGuideMsg *agm;    // for help
  106.     ULONG signals;                    // signals to wait on
  107.     struct rtHandlerInfo *rth;    // reqtools stuff
  108.  
  109.     Frames = GetNumber(TSMorphGadgets[GDX_Frames]);    // Get frames and start frame
  110.     Start = GetNumber(TSMorphGadgets[GDX_Start]);
  111.     if (Frames > 1) {                // No point displaying requester if 0 or 1 frame
  112.         // Determine Current frame number in correct range, using previously held value
  113.         FrameNumber = max(Start,FrameNumber);
  114.         FrameNumber = min(Start+Frames-1,FrameNumber);
  115.         DisableWindows(DI_GetFrame);    // Disable all other windows
  116.         while (ret == 2) {                // loop until Ok or Cancel (keep looping on Help)
  117.                                                 // if no amigaguide then 2 will never be returned
  118.             ret = CALL_HANDLER;            // reqtools stuff
  119.             if (rtGetLong(&FrameNumber,"Frame Number?",NULL,
  120.                                 RT_ReqHandler,        &rth,
  121.                                 RT_Window,            TSMorphWnd,            // same screen
  122.                                 RTGL_Min,            Start,
  123.                                 RTGL_Max,            Start+Frames-1,
  124.                                 RTGL_ShowDefault,    TRUE,
  125.                                 RT_Underscore,     '_',
  126.                                 RTGL_GadFmt,         handle?"_OK|_Help|_Cancel":"_OK|_Cancel",    // if amigaguide then help gadget
  127.                                 TAG_END) == CALL_HANDLER) {    // Opened requester
  128.                 while (ret == CALL_HANDLER) {                    // Loop well no gadget selected
  129.                     if (!rth->DoNotWait) {                        // Wait if poss.
  130.                         signals = Wait(rth->WaitMask | ASig);
  131.                     }
  132.                     ret = rtReqHandlerA(rth,signals,NULL);    // get gadget etc.
  133.                     if (ret == 2) {                                // help gadget
  134.                         help(H_FrameNumber);
  135.                     }
  136.                     if (signals & ASig) {                        // amigaguide message
  137.                           while (agm = GetAmigaGuideMsg(handle)) {
  138.                              ReplyAmigaGuideMsg(agm);
  139.                          }
  140.                      }
  141.                 }
  142.             }
  143.             else {                        // otherwise error so default Cancel
  144.                 ret = FALSE;
  145.             }
  146.         }
  147.         EnableWindows();    // enable all the windows
  148.     }
  149.     else {
  150.         if (!Frames) {    // number of frames = 0 so error
  151.             Error("Must have at least one frame","OK",NULL,HE_OneFrame);
  152.             ret = FALSE;
  153.         }
  154.         else {            // number of frames = 1 so only one choice
  155.             FrameNumber = Start;
  156.             ret = TRUE;
  157.         }
  158.     }
  159.     return (BOOL)ret;    // Cancel gadget is 0
  160. }
  161.  
  162. /* Closes and reopens images using new frame (in FrameNumber)
  163.  * the return value is that used by the main message loop
  164.  */
  165. int
  166. ReopenPictures(void) {
  167.     char buffer[257];    // Work buffer for points file name
  168.     LONG KeepFrame;    // Temporary frame number
  169.     if (!Saved) {        // if not saved then reset frame number and suggest user saves
  170.      KeepFrame = FrameNumber;
  171.      FrameNumber = OldFrame;
  172.      if (!SaveRequester()) {
  173.       return 1;            // user cancelled
  174.      }
  175.      FrameNumber = KeepFrame;    // either saved or abandoned so go to new frame
  176.     }
  177.     // Disable the windows and delete all the points
  178.     DisableWindows(DI_NextFrame);
  179.     DeleteAllPoints();
  180.     // Try and reopen image one and two
  181.     if (ReopenAPicture(GetString(TSMorphGadgets[GDX_FileOne]),&Pic1)) {
  182.         if (ReopenAPicture(GetString(TSMorphGadgets[GDX_FileTwo]),&Pic2)) {
  183.             // if ok then set up points filename and try and open
  184.             strcpy(TempFilename,savedfilename);
  185.             strcat(TempFilename,".%03ld");
  186.             sprintf(buffer,TempFilename,FrameNumber);
  187.             MyOpen(buffer,TRUE,FALSE);    // Note! do not complain if no points file for thisframe (yet)
  188.             // enable the windows
  189.             EnableWindows();
  190.             // This is nasty!! (and probably unnecessary)
  191.             // but CWTitle is already held as the screen title,
  192.             // so do not want to be writing whilst intuition is reading
  193.             // Probably better to just call SetWindowTitles twice (first time to nothing)
  194.             // But that could cause the screen to flicker?
  195.             Forbid();
  196.             sprintf(CWTitle,"TSMorph - Frame %03ld",FrameNumber);
  197.             Permit();
  198.             SetWindowTitles(ControlWindow,(UBYTE *)-1,CWTitle);
  199.             return 1;    // It worked
  200.         }
  201.     }
  202.     EnableWindows();
  203.     return 3;            // It did not work, so windows are closed, but keep going
  204. }
  205.  
  206. /* Opens an image in an (already) open window
  207.  * This is all very convoluted stuff!
  208.  * returns    : TRUE or FALSE for sucess failure
  209.  * filename    : Name of file
  210.  * pic        : pointer to a structure to hold all the stuff
  211.  */
  212. BOOL
  213. ReopenAPicture(char *filename,struct Picture *pic) {
  214.  char dirname[257];            // filename storage
  215.  char *e             = NULL;    // first part of error message
  216.  char *e1             = NULL;    // 2nd part of error message
  217.  LONG hnum            = 0;        // Help number for error
  218.  struct BitMap *OldBitMap = NULL;    // BitMap to keep
  219.  
  220.  // Set up new filename and display as screen title
  221.  // window title is done later (does not sound good?)
  222.  sprintf(dirname,filename,FrameNumber);
  223.  Forbid();            // Forbid whilst change window title - Nasty!!
  224.  strcpy(pic->filename,dirname);
  225.  Permit();
  226.  SetWindowTitles(pic->Win,(UBYTE *)-1,pic->filename);
  227.  // if we do not allow zoom then the super bitmap is the actual bit map
  228.  // so initialise so we do not lose it when we unload the brush
  229.  if (!ZoomAllowed) {
  230.   // Zero out current bitmap picture
  231.   OldBitMap = pic->ilbm->brbitmap;
  232.   pic->ilbm->brbitmap = NULL;
  233.  }
  234.  // Unload current frame (keeping bitmap)
  235.  unloadbrush(pic->ilbm);
  236.  // Try and load new brush - if this fails then flag error
  237.  if (!MyLoadBrush(pic,dirname)) {
  238.   e = (char *)-1;
  239.  }
  240.  if (!e) {
  241.   // fail if frame is not the same size as previous
  242.   if ((pic->ilbm->Bmhd.w != Width) ||
  243.         (pic->ilbm->Bmhd.h != Height)) {
  244.    // if no zoom allowed then reset the bitmap to the original - freeing the new one
  245.     if (!ZoomAllowed) {
  246.      freebitmap(pic->ilbm);
  247.      pic->ilbm->brbitmap = OldBitMap;
  248.     }
  249.     e = "Frames must all be the same size";
  250.     hnum = HE_FAllSize;
  251.   }
  252.   else {
  253.     SetWindowTitles(pic->Win,FilePart(pic->filename),pic->filename);    // This refreshes the titles
  254.     if (ZoomAllowed) {
  255.     // If we allow zoom then reset up BitScale stuff and scale or copy
  256.      pic->BitScaleArgs.bsa_SrcBitMap     = pic->ilbm->brbitmap;
  257.      /* Either scale image 2x or straight copy    */
  258.      if (Zoom) {
  259.       BitMapScale(&(pic->BitScaleArgs));
  260.      }
  261.      else {
  262.       BltBitMap(pic->ilbm->brbitmap,0,0,
  263.                       &(pic->BitMap),0,0,
  264.                       pic->ilbm->Bmhd.w,pic->ilbm->Bmhd.h,
  265.                       0xC0,0xff,NULL);
  266.      }
  267.     }
  268.     else {
  269.      // Zoom is not allowed - so copy the new bit map to the old bit map
  270.      BltBitMap(pic->ilbm->brbitmap,0,0,
  271.                     OldBitMap,0,0,
  272.                       pic->ilbm->Bmhd.w,pic->ilbm->Bmhd.h,
  273.                       0xC0,0xff,NULL);
  274.      // free the new bit map and set the image back
  275.      freebitmap(pic->ilbm);
  276.      pic->ilbm->brbitmap = OldBitMap;
  277.      // All because we can not change the bitmap of a super bitmap window
  278.     }
  279.     // Resync the display to the new bitmap display
  280.     LockLayerRom(pic->Win->RPort->Layer);
  281.     CopySBitMap(pic->Win->RPort->Layer);
  282.     UnlockLayerRom(pic->Win->RPort->Layer);
  283.   }
  284.  }
  285.  else {
  286.   // failed loading new image
  287.   // so close file
  288.   closeifile(&(pic->ilbm->ParseInfo));
  289.   if (!ZoomAllowed) {
  290.    // if no zoom allowed then free new bit map and restore old
  291.     freebitmap(pic->ilbm);
  292.     pic->ilbm->brbitmap = OldBitMap;
  293.   }
  294.   // set up error stuff
  295.   e = "Failure loading Image '%s'";
  296.   e1 = dirname;
  297.   hnum = HE_LoadImage;
  298.  }
  299.  // display error (if required) and return status
  300.  if (e) {
  301.   if (e != (char *)-1) {    // do not think this is possible?
  302.    Error(e,"OK",e1,hnum);    // we can actually display two error message
  303.   }                                // as MyLoadBrush() may have already displayed one
  304.   return FALSE;
  305.  }
  306.  else {
  307.   return TRUE;
  308.  }
  309. }
  310.